{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Engineer features and convert time series data to images"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Imports & Settings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To install `talib` with Python 3.7 follow [these](https://medium.com/@joelzhang/install-ta-lib-in-python-3-7-51219acacafb) instructions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:21:57.052353Z",
     "start_time": "2020-06-21T21:21:57.049485Z"
    }
   },
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:21:57.855651Z",
     "start_time": "2020-06-21T21:21:57.054734Z"
    }
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import pandas as pd\n",
    "\n",
    "from scipy.spatial.distance import pdist\n",
    "from scipy.cluster.hierarchy import dendrogram, linkage, cophenet\n",
    "\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.feature_selection import mutual_info_regression\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:21:57.860367Z",
     "start_time": "2020-06-21T21:21:57.856833Z"
    }
   },
   "outputs": [],
   "source": [
    "MONTH = 21\n",
    "YEAR = 12 * MONTH"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:21:57.867940Z",
     "start_time": "2020-06-21T21:21:57.861361Z"
    }
   },
   "outputs": [],
   "source": [
    "START = '2001-01-01'\n",
    "END = '2017-12-31'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:21:57.876846Z",
     "start_time": "2020-06-21T21:21:57.868892Z"
    }
   },
   "outputs": [],
   "source": [
    "sns.set_style('white')\n",
    "idx = pd.IndexSlice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "results_path = Path('results', 'cnn_for_trading')\n",
    "if not results_path.exists():\n",
    "    results_path.mkdir(parents=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Load Model Data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:22:06.006063Z",
     "start_time": "2020-06-21T21:21:57.878061Z"
    }
   },
   "outputs": [],
   "source": [
    "with pd.HDFStore('data.h5') as store:\n",
    "    features = store.get('features')\n",
    "    targets = store.get('targets')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:22:06.060274Z",
     "start_time": "2020-06-21T21:22:06.008665Z"
    },
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "MultiIndex: 2378283 entries, ('A', Timestamp('2001-01-02 00:00:00')) to ('ZTS', Timestamp('2017-12-28 00:00:00'))\n",
      "Columns: 300 entries, 06_RSI to 85_CMA\n",
      "dtypes: float64(300)\n",
      "memory usage: 5.3+ GB\n"
     ]
    }
   ],
   "source": [
    "features.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:22:06.098347Z",
     "start_time": "2020-06-21T21:22:06.062001Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "MultiIndex: 2378283 entries, ('A', Timestamp('2001-01-02 00:00:00')) to ('ZTS', Timestamp('2017-12-28 00:00:00'))\n",
      "Data columns (total 4 columns):\n",
      " #   Column      Dtype  \n",
      "---  ------      -----  \n",
      " 0   r01_fwd     float64\n",
      " 1   r01dec_fwd  float64\n",
      " 2   r05_fwd     float64\n",
      " 3   r05dec_fwd  float64\n",
      "dtypes: float64(4)\n",
      "memory usage: 81.9+ MB\n"
     ]
    }
   ],
   "source": [
    "targets.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Select Features using Mutual Information"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.246534Z",
     "start_time": "2020-06-21T21:22:06.099687Z"
    }
   },
   "outputs": [],
   "source": [
    "mi = {}\n",
    "for t in [1, 5]:\n",
    "    target = f'r{t:02}_fwd'\n",
    "    df = features.join(targets[target]).dropna().sample(n=100000)\n",
    "    X = df.drop(target, axis=1)\n",
    "    y = df[target]\n",
    "    mi[t] = pd.Series(mutual_info_regression(X=X, y=y),\n",
    "                      index=X.columns).sort_values(ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.267351Z",
     "start_time": "2020-06-21T21:45:29.247482Z"
    }
   },
   "outputs": [],
   "source": [
    "mutual_info = pd.DataFrame(mi)\n",
    "mutual_info.to_hdf('data.h5', 'mutual_info')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.277173Z",
     "start_time": "2020-06-21T21:45:29.268683Z"
    }
   },
   "outputs": [],
   "source": [
    "mutual_info = pd.read_hdf('data.h5', 'mutual_info')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.286708Z",
     "start_time": "2020-06-21T21:45:29.278447Z"
    }
   },
   "outputs": [],
   "source": [
    "mi_by_indicator = (mutual_info.groupby(mutual_info.\n",
    "                                       index.to_series()\n",
    "                                       .str.split('_').str[-1])\n",
    "                   .mean()\n",
    "                   .rank(ascending=False)\n",
    "                   .sort_values(by=1))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.431052Z",
     "start_time": "2020-06-21T21:45:29.287560Z"
    },
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "mutual_info.boxplot()\n",
    "sns.despine();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.844543Z",
     "start_time": "2020-06-21T21:45:29.432316Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAagAAAEYCAYAAAAJeGK1AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+j8jraAAAgAElEQVR4nO3deXyNd/7//0cSidQeS63JiGqlqijGklhKYwuHShpiOaqCapmiqqIM/czQxjK0tIo2UxV7LGNJVIkSYaToojW1VyS2tEUiC9nO7w+/nK8UQeQkV9Ln/XZzuznX+nonufLK+329r9dlZ7FYLIiIiBiMfVEHICIicjdKUCIiYkhKUCIiYkhKUCIiYkhKUCIiYkhKUCIiYkhKUMVMfHw8DRo0YNCgQXesCwoKokGDBly5ciXPY8TFxfG3v/3tkeIwm818+eWXdyzfsGEDr7766n33j46OpmPHjrz00kvcuHHjkWJ5WEOHDrV+jYYPH86pU6cK7dy9e/cmKSmJ69evM3jwYOvyB/m+3W7dunWMHDnynutjYmJo3LgxvXv3pnfv3phMJgYPHsz+/fsfKf7bLViwgNatW1vPkfPvxx9/LLBzPKpXX32VDRs23LF8w4YNNG/e3Bpzr1696NSpE2+//TY3b96873GnTJnCTz/9ZIuQ5TalijoAeXilS5fml19+4fz589SuXRuA1NRUvv322wfa/8KFC/zyyy+2DPG+wsPD8ff35/XXXy/0c+/bt8/6/08//bRQz71p0ybg1h8a+flFfu3aNebOncuWLVto2bJlntu6ublZzwdw7NgxAgMDWbhwIU2aNHnoc9+Nj48PU6dOLZBjFbYWLVqwePFi6+ebN2/Sv39/Nm7cSEBAQJ777t+/n379+tk6xD899aCKIQcHB7p3786WLVusy7766iteeOEF6+eYmBh69ux5x+esrCymTJnCuXPnCAwMJD4+nueee8663e2fU1NTefvtt+nXrx9du3bF19eXM2fOPHCcCxYsICgoiMDAQLp168bLL79MQkICn332GZGRkaxatYqZM2eSkZHBP//5T3x8fDCZTEyePJnk5GQAOnXqxNixY+nevTs7duygU6dOzJ07l759+9K1a1fCwsKYNGkSvXr1wtfXl8uXLwPw9ddfExAQgK+vL88//zwffPABAJMmTQLg5Zdf5uLFi3Tq1MmaKNasWUPPnj3p1asXQ4cOtSbxoKAgpk+fjtlspnPnzowePZqUlJRcbf3555/p0KGD9XNgYCATJ04EID09nVatWnH9+nVrT2nSpEncuHGD3r17k5WVZf16+fr60qlTJ1asWHHXr+m2bdt4/PHHrcd+GB4eHpjNZpYuXQrA999/z8CBA/H39+f555/nnXfeAeCTTz5h/Pjx1v0OHTrEiy+++FDnetDv6dKlS5kwYYJ1n2bNmrF+/Xrref39/cnOzmb69On4+/vj4+ND9+7dOXz4MHDrezNy5Eh69OjB7NmzuXz5Mq+88go9evRg+PDh/Prrrw8c87Vr10hOTqZixYoAXL58mVGjRuHr64vJZGLRokUAzJs3j4SEBN566y1++OGHO0YTbv/cqFEjxowZQ9euXfnxxx959tlnWbBgAQEBAXTq1ImVK1cC8OuvvzJ06FD69OlDnz59rD+vf3ZKUMXUiy++mOuv4//85z/06dPnvvs5ODgwffp03NzcCAkJyXPbqKgoKlSowJo1a9i+fTuNGjW65y/Oezl06BAffvghX375JY899hirV69m2LBhdOrUiSFDhjBx4kQ++eQTEhIS2LRpE5s2bSI7O5tZs2ZZj/Hkk0+ybds2OnfuDNz6S3ft2rWMGTOGqVOn8vLLL7N582Zq1qzJxo0bsVgs/Pvf/yY4OJgNGzawZs0alixZwpUrV3j//fcB+OKLL6hZs6b1HP/973/57LPPWLZsGZs3b6Znz56MGjWKnEIrP/30EyEhIURERHD+/Pk7hjeffvppSpUqxYkTJ7hx4wZnzpzhwIED1mM3btyY8uXLW7d///33cXZ2ZtOmTTg4OADg6urKhg0b+OijjwgODiYjI+OOr2f//v0ZPXo0Tk5OD/V9yOHh4cGJEycAWLZsGW+88QZhYWGEh4eza9cufvrpJ/r27cvu3bu5du0aAGvXrr1njyIiIiLX8N5HH30E8MDf0y5duhAdHU12djaHDx+mTJky1mHIXbt20aVLF3744QcSEhJYs2YNERER9OnTJ1fP98aNG4SHhzNhwgT+8Y9/0KRJE8LDw5kyZUqeIwWHDh2id+/edOvWjdatWzNmzBiGDh1K9+7dAZgwYQJ+fn5s2LCBdevWsX//fiIiIhg3bhyPP/44c+bMuW9PNCMjg44dO7J9+3aeffZZ0tPTcXFxYfXq1cyfP5/333/f+vNcp04dNm7cyIoVK4iNjeX69ev3+3aWeBriK6YaNWqEg4MDP/30E1WqVCElJYWnnnqqQM/RrVs3XF1dCQ0NJTY2lm+++SZXb+tBtGzZknLlygHQsGFDEhMT79gmKiqKcePG4ejoCNz6C3TUqFHW9S1atMi1fZcuXYBbv9CrVq2Kh4cHcGtIKzExETs7OxYtWsTu3bvZunUrp0+fxmKxkJaWds849+7di4+PD5UrVwbA19eXGTNmEB8fD0C7du2sSeGpp566azs6d+5MVFQUTz75JK1bt+b48eOcPHmSyMhIa8x5yenxPv3006Snp5OcnIyLi8t993sYdnZ2ODs7AxAcHExUVBSLFi3izJkz3Lx5k9TUVKpUqcLzzz/Ppk2bePHFF4mOjmbatGl3Pd69hvge9Htaq1YtatasyU8//cTevXsZMWIES5YswWKxsGvXLpYsWYKbmxsVK1Zk9erVxMXFERMTQ9myZa3Hat68ufX/+/fvt/Yu//KXv9CqVat7fi1yhviys7NZuHAhW7dupVu3bsCt0YODBw+SmJjIhx9+aF127NgxfHx87v+F/sN5bpcz0vHMM8+Qnp5Oamoq7dq1Y8SIEVy8eBFPT0/Gjx+f6w+aPyv1oIqxXr16sXnzZjZt2kTv3r1zrbOzs+P2Mot3+2v8ftutXLmSyZMn4+zsjMlkomfPnjxs6cacX4Z3O1eO7Oxs7Ozscn2+PY4yZcrk2v723kPOL8Dbpaam0qdPH44ePUrDhg15++23KVWqVJ6xZ2dn37HMYrGQmZn5wO3w9vZmz5497Nu3Dy8vLzw9PYmOjiYqKgpvb+97njtHqVKlrMfPOf+Dmjx5srUXs2rVqntu9+OPP1r/kBk0aBB79uyhXr16jBo1iscff9x6zoEDB7J+/Xq2bt1Kly5dciWEB/Ew31Nvb2+ioqLYt28fXbt2pVatWkRERODs7Iybmxu7d++2Trx54YUX6N+/f65z3X6sP35vcr6mebG3t2f06NHUrl2boKAga7wWi4XVq1dbe4Fr1qy55wSgvK61P/78li5d2hprzr6NGzcmMjKSfv36cf78efz9/TUJAyWoYq137958+eWXRERE5LrfBFC5cmUuXLjA77//jsViITw83LrOwcHBehFVqFCBjIwM60y227eLjo6mT58++Pv74+7uzq5du6z3SwpSu3btWLVqFRkZGWRnZ7NixQq8vLzyfbzY2FiSk5MZO3YsnTp1IiYmhvT0dGsScnBwsCae22OIiIiwzqRbv349lSpV4i9/+csDn7dZs2bExcWxe/duPD098fLy4osvvqBu3bp39IRKlSpFVlbWQyf8e5kxY4b1F+kff4HnOHLkCKtWreLll18mKSmJH3/8kbfeeosuXbpw6dIlzp07Z/0aNWvWDHt7e0JCQu47YeBuHuZ72qVLF7Zs2UJ2djbVq1fHy8uL2bNnW3ud+/bto2PHjgwYMIBGjRqxc+fOe/4ctmvXjjVr1gC3JgPFxMQ8cMzTpk1j37597Ny5k3LlytG0aVM+//xzAJKSkujfvz+RkZFA7p+hypUrW5PJqVOnOH78+AOfM8ecOXNYuHAh3t7eTJ48mfr163Py5MmHPk5JowRVjFWvXp0nnniCunXrUqlSpVzr6tevT0BAAH5+fvTt25c6derkWle6dGleeuklypUrx4QJExg+fDh+fn7Wv+7g1nTsNWvWYDKZGDhwIM888wznzp0r8Ha89tprVK1alRdffJHu3buTmZnJ5MmT8328Bg0a8Pzzz9O9e3e6d+/O119/Tf369YmNjQVuDV2azWbrvRgALy8vhgwZwssvv0yPHj34z3/+w+LFi7G3f/BLxN7envbt21O2bFkqV65M8+bNSUxMvOvwXrVq1WjcuDE9evTg6tWr+W5rXs6dO2ftVfXp04fZs2czZ84cPDw8qFChAiNGjKBPnz707NmTJUuW0KxZM+vXCG4Ncz7++OPWIdSH8TDf0/r162NnZ0ebNm0AaNu2LRcvXqRr164ABAQE8M0332AymejTpw+urq7Ex8fftdc7bdo0Tp8+Tffu3Zk8efJDxe7m5sbw4cOt94XmzJnDDz/8gMlkwt/f3zqBBm4N506YMIHo6Ghee+019u3bR8+ePZk/f/4dQ3oP4uWXX+bYsWP07NkTPz8/6tSpQ48ePR76OCWNnV63ISJ/lJmZyejRo+nVq9dD33MRKSjqQYlILqdOnaJNmza4uLhYJw2IFAX1oERExJDUgxIREUNSghIREUMqEQkqMDCwqEMQEZECViISlK2m6YqISNEpEQlKRERKnhKRoDQPUUSk8N3IKPjKMrcrkGKxMTExjBo1ii1btlgrRM+ZM4d69erh6+vLDz/8wMCBA1m5ciWNGzfms88+Y8+ePSQlJZGQkED9+vUBWLp0KU2aNLEWJM0pk/Kvf/0LV1fXe57fzg7qBoXfc72IiBS8s8G2rXZRYNXMHR0dmTRpEp9//nmuIpEAYWFhvPLKK9YENWzYMIYNG0ZMTAyrV69m3rx51m0rVqxIaGio9fPq1av5/PPPi+1L0UREJH8KbIivdevWVKxY8Y73BaWkpHDgwAFGjx7Nt99++1CvtYZbBR8rVKhQUGGKiEgxUaD3oN59912WLl3K2bNnrcsiIiLo3LkzpUuXpnv37qxbty7PYyQmJmI2m+nTpw8dO3bk5s2bDB8+vCDDFBGRYqBAX1jo4uLCO++8Q1BQEM2aNQNuDe85ODgQGBjIjRs3uHTpEsOGDbtnleicIb6srCyCgoJwdHR86HfRiIhI8Vfgb9Tt1KkTO3bsYOPGjbz++utkZWWxdu1a6/pXXnmFr7/+2vpWyXtxcHDgn//8J71796ZFixY8//zz99zWYrH9zToREcntRkYWzo4ONju+TaaZ57yFdd68eXe86dXf3/+O+1T34uzszIwZM/jnP/9JamrqPbf7w5wMEREpBLZMTlBCqpn7+vqyYcOGog5DREQKUIl4UFdEREoeJSgRETEkJSgRETGkAp/Fd7uYmBjGjh1L/fr1sVgsZGZmMmPGDD799FOOHj1KpUqVSE9P58knn2TatGk4Ojri5eXFvn37rMeIiooiIiKC4ODge56n+N9Fk6Jk65lIIpI/Nk1QcKvCRE4po+joaGbNmoWLiwsTJkygffv2AIwfP57IyEi6deuWr3OoFp88Cj2iIGJMhTrEl5SURO3atXMty8rKIiUlhVq1ahVmKCIiYnA270EdOHAAs9lMeno6x48fZ/HixWzcuJHZs2fz6aefkpCQQPny5XF3dwf+X6mjHNeuXeOZZ56xdZgiImIwhTrEd+bMGQICAvD09Mw1xPfhhx8SHBzMjBkz7qhmnnMPSkRE/lwKdYivatWqd11es2ZNMjIyCjMUERExuEIb4rO3tyclJYWgoCC++eYb6xCfvb092dnZvPfee/k+h2rxyaPQLD4RY1KpIxERMSQ9qCsiIoakBCUiIoakBCUiIoakBCUiIoZks1l8t9fhA7h58yYmk4mjR49a6/DBrUoS//d//8eTTz5JSkoK8+bN4+eff8be3p6yZcsyceJE60O891L8p3lIfmj2nUjJZtNp5rc/pJuenk63bt3w8PDI9ZDunj17+PDDD/noo4/4+9//znPPPceUKVMAOHbsGKNGjWLNmjWUL1/+nudRLb4/Jz1aIFKyFdoQX3JyMvb29pQqlTsnJiYmUqZMGa5cucKJEydylTny8PCgY8eOfPXVV4UVpoiIGIRNe1A5D+na2dnh6OjI3//+d7Zt25brId3HH3+cCRMmEB8fj6ur6x3HcHV15cKFC7YMU0REDKjQhvhybNu2LdcQX47s7Oy7JqLY2FieeOIJW4YpIiIGZJhZfDVq1MDNzY0VK1ZYlx09epRdu3bRpUuXIoxMRESKgs1r8T2MmTNnMmvWLPz9/XFwcKBChQosXLiQChUq5LmfavH9OWkWn0jJplp8IiJiSIYZ4hMREbmdEpSIiBiSEpSIiBiSEpSIiBiSTWbx/bEOX0pKCnXq1GHOnDkkJyczc+ZMLly4QFZWFjVr1iQoKIhq1aoBcOjQIT7++GMyMzNJTU3F19eXgQMH5nm+4j/NQ26n2XkiAjacZv7Hh3THjx9PZGQkoaGhDB06FG9vbwD279/Pq6++SlhYGBcuXGD69Ol89tlnVK1alRs3bjB48GBcXV3veLD3dqrFV7LokQERgUJ6Dio9PZ2EhATi4uIoX768NTkBeHp64ubmxsGDBzl06BAvvvgiVatWBcDZ2ZmQkBDKlClTGGGKiIiB2CxB5dTh+/3337G3t6dv375UrVqVhISEO7bNqbeXkJCAh4dHrnV5VTEXEZGSy2aTJFq3bk1oaCgrVqzA0dGROnXqUL16dc6fP3/HtrGxsdSsWZNatWpx6dKlXOuOHTvGzz//bKswRUTEoGw+i8/FxYXZs2czZcoUXF1d+e2339i1a5d1fVRUFLGxsbRs2ZKePXsSFhbGlStXgFuTK6ZOnXrXXpeIiJRshXIPqn79+pjNZqZPn86iRYt47733WLx4MXCrSOySJUtwcHCgTp06TJgwgdGjR+Pg4EBKSgovvfQSHTp0yPP4qsVXsmgWn4iAavGJiIhB6UFdERExJCUoERExJCUoERExJCUoERExpAJLUIMHD+bIkSPArcoRzZs3JyQkxLp+0KBB/PWvf6V79+659vvqq69o0KAB8fHx1mXTpk3jxRdffOBzF/9pHsXXjYysog5BREqoAptm3rZtWw4dOkTjxo05fPgwbdu2Zffu3QQGBnLz5k0uXryIh4cHv/32Gz///DNPP/00AOHh4dSuXdt6nLS0NL799lueeuopYmJiaNWq1X3PrVp8RUfT+0XEVgqsB+Xp6cmhQ4cA2LNnD/7+/ly/fp3r16/z3Xff0bJlSwB69OjB1q1bAUhKSuLmzZvW2nsA27Zto02bNvTp04cVK1YUVHgiIlLMFFiCatiwIWfOnMFisXDw4EFatmxJmzZt2L9/P9988w3t2rUDoFOnTkRFRWGxWNi+fTvdunXLdZywsDD8/f3x9PTkf//7H5cvXy6oEEVEpBgpsARlb2+Ph4cHUVFRVKtWDScnJ9q3b8+3337L4cOH8fT0BKB06dI8/fTTfPfdd+zYsYPOnTtbj3H69GlOnjxJcHAww4cPx87OjlWrVhVUiCIiUowU6Cw+Ly8vFi9ebO0tNW/enP/9738AVKpUybpdz549Wbp0KRUrVqRs2bLW5WFhYYwbN46QkBBCQkL44osvWL9+Penp6QUZpoiIFAMFWovP09OTKVOmMGvWLACcnJwoX748DRs2zLWdl5cXQUFBvP/++9ZlGRkZhIeHs2nTJuuyWrVq4eHhwfbt2zGZTPc8r2rxFR3VzRMRW1EtPhERMSQ9qCsiIoakBCUiIoakBCUiIoZUIhJU8b+LVvyoxJGI2JrN3qgbExPD2LFjqV+/vnWZi4sLZcqUYefOnezfvx8nJycAjh49iq+vL8uWLbOWNlqyZAnLli0jMjKS0qVL53kulToqfJo1KSK2ZtNXvrdu3Zp58+blWhYUFES1atWIiorC29sbgC1btuDq6ppruy1btuDj40N4eDi+vr62DFNERAyoSIb4bq/Hl52dzdGjR3n22Wet62NiYnBzcyMgIED1+ERE/qRs2oM6cOAAZrPZ+rlDhw4ANG7cmB07dpCamsr3339Pq1atOH36tHW7nHp89erVw8nJiR9++IEmTZrYMlQRETGYIhnig1tFYyMjI9m/fz+vvfaadbvExESioqK4cuUKoaGhJCcns3z5ciUoEZE/GZsmqLyYTCZmzJiBnZ0dbm5u1uWbN2/Gz8+PiRMnArfeD/XCCy9w5coVKleufNdjqdRR4VOJIxGxtUId4gOoUqUKAPXq1ePq1av4+fnlWh8WFmat5Qfw2GOP0aVLF9auXcvIkSPveh47uwIOXO5LyUlEbE21+ERExJBKxIO6IiJS8ihBiYiIISlBiYiIIZWIBFX876LZnmrniUhxY/Np5rfX5LNYLGRmZjJjxgw+/fRTjh49SqVKlUhPT+fJJ59k2rRpODo64uXlxb59+x74HKrFd3+ahi8ixU2hPAd1+wO70dHRzJo1CxcXFyZMmED79u0BGD9+PJGRkXTr1q0wQhIREYMr9CG+pKQkateunWtZVlYWKSkp1KpVq7DDERERgyqUHlTOA7vp6ekcP36cxYsXs3HjRmbPns2nn35KQkIC5cuXx93dvTDCERGRYqDQh/jOnDlDQEAAnp6euYb4PvzwQ4KDg5kxY0ZhhCQiIgZX6LX4qlatetflNWvW5Pz58/k6pmrx3Z9q54lIcVOoQ3z29vakpKQQFBTEN998Yx3is7e3Jzs7m/feew+Aa9eu5XpJ4dChQ+nZs+c9j69afPen5CQixY1q8YmIiCGViAd1RUSk5FGCEhERQ1KCEhERQ8p3goqJiaFBgwZERETkWm4ymayvdb98+TJNmjRh27ZtubY5efIkI0aMwGw24+fnx/z587FYLMTHx9OsWTPMZjODBg2ib9++LF++/L6xFMe7aKqNJyKSt0eaxVevXj22bt2Kj48PAMePHyctLc26fsOGDQwePJiVK1fSvXt34FYliTfffJMFCxZQt25dsrKyGDNmDKtXr6Zdu3bUr1+f0NBQADIyMhg1ahS1atWiU6dO94yjONbi07R4EZG8PdIQn4eHBxcvXiQpKQmAzZs3YzKZALBYLGzatIlXXnmFjIwMTpw4AUBkZCStWrWibt26ADg4ODBz5sw7Xv0O4OjoyODBg+/opYmISMn3yPegOnfuzI4dO7BYLBw5coTnnnsOgP/+97889dRTVK5cGT8/P1asWAFAQkICrq6uuY5RtmxZnJyc7nr8qlWrcvXq1UcNU0REiplHTlAmk4mIiAgOHjxIixYtrMvXrl1LfHw8gYGBbNmyhW3btnH9+nVq1arFpUuXch0jLi6OgwcP3vX458+fp0aNGo8apoiIFDOPnKBcXV1JTU0lNDSUXr16AXD16lV++OEHwsLCCAkJYdmyZXTp0oWNGzfSsWNH9u7dy7lz54Bb95mCg4OtQ4C3S09PZ9myZfToofs1IiJ/NgVS6sjHx4dNmzbh7u5u7Q35+/vj4PD/yuv07duXt99+G7PZTHBwMFOmTMFisZCSkkLHjh0ZMGAA58+f59SpU5jNZuzs7MjMzMRkMuHp6Znn+YtjLT7VxhMRyZtKHYmIiCHpQV0RETEkJSgRETEkJSgRETEkJSgRETEkm72wcMmSJezfvx97e3vs7OwYN24cy5cvZ+fOnezfv9/6YO7Ro0fx9fVl2bJlAIwdO5b69etjsVjIzMxkxowZPPHEE3meqzhN89DsPRGRB2OTBHXq1Cl27drFqlWrsLOz4+eff2bixIk0bNiQatWqERUVhbe3NwBbtmzJVVmidevWzJs3D4Do6GhmzZrF4sWL8zxfcarFV9ymw4uIFBWbDPFVrlyZCxcusG7dOi5fvszTTz/NunXrAOjRowdbt24FIDs7m6NHj/Lss8/e9ThJSUnUrl3bFiGKiIjB2aQHVblyZT755BOWL1/Oxx9/jLOzM+PGjQOgcePG7Nixg9TUVL7//ntatWrF6dOnrfseOHAAs9lMeno6x48fv2/vSURESiabJKjY2FjKlSvH+++/D8CPP/7IiBEjaNKkCQCdOnUiMjKS/fv389prr1mH9CD3EN+ZM2cICAggKioKZ2dnW4QqIiIGZZMhvuPHj/Puu+9y8+ZNANzd3Slfvry19JHJZOI///kPv/76K25ubvc8TtWqVW0RnoiIFAM26UF16dKF06dP4+/vT5kyZbBYLLz99tvs3LkTuPWiw6tXr971HVA5Q3z29vakpKQQFBR0395TcarFp1l8IiIPRrX4RETEkPSgroiIGJISlIiIGJISlIiIGJISlIiIGFKBJaiYmBjatGmD2WzGbDbj6+vLG2+8wS+//EKDBg1YsmRJru1HjhyJ2Wzm4MGDDB8+3Lp88eLFtGzZkszMTODWrL5Ro0bleW4jT/O4kZFV1CGIiBRLBTrN/PaHbAHGjx/Prl27cHNzY/v27YwYMQKAa9euERsbS9WqVWnatCnHjx8nOzsbe3t7oqOjad26Nd9++y0tW7bkm2++oV27dnme18i1+IrL9HcREaOx2RBfeno6CQkJVKhQARcXF6pUqWItaRQREUG3bt0AcHR0pGHDhhw/fpykpCSys7Px8fFh9+7dABw8ePC+CUpEREqeAk1QOQ/Z+vj44OvrS+fOnWnTpg1wq0hsePitXk5kZKS1mjmAp6cnhw4dIjo6Gk9PT7y8vNi/fz83b97k+vXrKhgrIvInVKAJqnXr1oSGhrJixQocHR2pU6eOdZ23tze7du0iPj6eatWq5aoO4eXlxaFDh9i7dy8dOnSgfPnylC9fnr1799KyZcuCDFFERIoJmwzxubi4MHv2bKZMmcKvv/4KQNmyZXF3d2f27Nn07Nkz1/ZPPPEECQkJnDhxgmeeeQaAtm3bEhISouE9EZE/KZu9Ubd+/fqYzWY+//xz6zKTycTUqVOZO3cuZ8+ezbV93bp1sVgs2NnZAdC+fXs+/vjjB+pBGbkWn2rviYjkj2rxiYiIIelBXRERMSQlKBERMSQlKBERMSQlKBERMSSbJaiTJ08yYsQIzGYzfn5+zJ8/n7i4uDzr8uW4eWhlVsYAABb7SURBVPMmXl5efPbZZw90LiNO81ANPhGRR2OTaeZJSUm8+eabLFiwgLp165KVlcWYMWOIjo7Osy5fju3bt+Pj48PGjRsZOnQo9vZ551Ej1uIz6rR3EZHiwiY9qMjISFq1akXdunUBcHBwYObMmbRu3TrPunw5wsLC8PPzw8PDgz179tgiRBERMTibJKiEhARcXV1zLStbtiyOjo5A3nX5zp49S1paGh4eHvj5+bFixQpbhCgiIgZnkwRVq1YtLl26lGtZXFwcFy9eBPKuyxcWFkZaWhqBgYGEhIRw+PBhYmNjbRGmiIgYmE3uQXXs2JHFixfTv39/3NzcyMjIIDg4GE9PTyB3XT5/f3/rfpmZmURERLBx40YqVaoEwCeffMLKlSuZNGnSPc9nxFJHKnEkIvJobNKDKleuHMHBwUyZMgWz2Uy/fv3w8PCgffv21m1MJhOHDx+2vo4DYNeuXTzzzDPW5AS3yhht2rSJtLS0e57v/y/fZyhKTiIij0a1+ERExJD0oK6IiBiSEpSIiBiSEpSIiBhSiUhQRryLplJHIiKPxibTzE+ePMns2bNJS0sjNTWVDh060KdPH7y9vRk/fry1zBHcqsOXkpJCaGgoFouFlStXsnXrVkqVuhXasGHD6NChQ57nU6kjEZGSp8AT1KPU4VuzZg3ffvstS5cupXTp0ly9epURI0ZQsWJFmjZtWtChioiIgRX4EN+j1OFbvnw5kydPpnTp0gC4uLgwevRoVq1aVdBhioiIwRV4gnqUOnxXr16lcuXKufZ1dXXlwoULBR2miIgYXIEnqEepw1euXDmuXbuWa9/Y2Fhq1qxZ0GGKiIjBFfg9qPzW4QMYNGgQ06dP57333sPJyYnff/+djz76iMmTJ+d5TtXiExEpeQo8Qd1eh89isZCSkkLHjh1p3749mzZtAm7V4Zs6dSpz587l7Nmz1n3NZjNZWVkMHDiQUqVKYWdnx+uvv06zZs3yPKdq8YmIlDyqxSciIoZUIh7UFRGRkkcJSkREDEkJSkREDMkmpY7uJSYmhrFjx1K/fn0AUlJSqFOnDnPmzCE8PJyNGzfi4OCAxWJh2LBhtG3blg0bNnDmzBneeuutex7XiHfRNItPROTRFGqCAmjdujXz5s2zfh4/fjzh4eEsXLiQ8PBwnJycuHz5Mv7+/uzevfuBjqlafCIiJU+RDvGlp6eTkJBAjRo1yMrKYtWqVZw7d47q1auzc+dO7O01Aiki8mdV6D2oAwcOYDab+f3337G3t6dv3760adOGzz//nC+++IJhw4aRkZHB8OHDGTBgQGGHJyIiBlFkQ3xXr15l6NCh1KlTh8uXL3Pjxg2mTp0KwC+//MKwYcNo3rx5YYcnIiIGUWRjaC4uLsyePZspU6YQHx/PW2+9RWJiIgC1a9fGxcXFWmBWRET+fAq9B3W7+vXrYzab+eKLLxg8eDAvv/wyzs7OZGVl4e/vT7169fj+++/vexzV4hMRKXlU6khERAxJ0+RERMSQlKBERMSQlKBERMSQlKBERMSQHjpBxcTE0KBBAyIiInItN5lMBAUFPdAxvLy8Hmi7a9eusWXLlvtuZ7RpHjcysoo6BBGRYi9f08zr1avH1q1b8fHxAeD48eOkpaUVaGA5x921axcmkynP7YxWi89oU95FRIqjfCUoDw8Pzp49S1JSEhUqVGDz5s2YTCYuXrzI8uXL+eqrr8jMzKR8+fIsWLCArVu3sn79erKzs3njjTesx5k7dy7Xr19n6tSpfPnllyxduhR7e3uaN2/OW2+9xaJFizh27Bhr1qyhX79+BdZoERExvnzfg+rcuTM7duzAYrFw5MgRnnvuObKzs7l27RpLly5l5cqVZGZm8uOPPwJQoUIFVq1aRZs2bQCYOXMmmZmZTJs2jcTERBYsWMDSpUtZtWoVly9fZt++fYwcOZLWrVsrOYmI/Anlu5KEyWTi3XffxdXVlRYtWgBgb2+Po6Mjb775JmXKlOHSpUtkZmYC4O7ubt33t99+4/jx47i5uQFw7tw5rly5wogRI4Bb74mKi4vLtY+IiPy55DtBubq6kpqaSmhoKG+++SZxcXEkJyezc+dOwsLCSEtLw9fXl5xCFbe/OqNq1aqEhIRgNpuJioqiUaNG1KxZk3//+984OjqyYcMGnn76aZKTk8nOzn70VoqISLHzSLX4fHx82LRpE+7u7sTFxeHg4MBjjz2Gr68vTk5OVKtWjYSEhLvua2dnx3vvvUdgYCBr165lyJAhmM1msrKyqF27Nt27dycpKYkTJ06wdOlShgwZcs84jFaLT3X4REQenWrxiYiIIelBXRERMSQlKBERMSQlKBERMSQlKBERMSSbJaiYmBjGjRuXa9mcOXPYsGEDDRo0YMmSJbnWjRw5ErPZDIDZbOb06dMPfK6imuahmnsiIrZTJK98d3NzY/v27dYHc69du0ZsbCxVq1bN1/GKqhafkaa2i4iUNEUyxOfi4kKVKlWsvaSIiAi6detWFKGIiIhB2TRBHThwALPZbP23detW67oePXoQHn6r1xMZGYm3t7ctQxERkWLGpkN8rVu3Zt68edbPc+bMsf7f29ubgQMH4uvrS7Vq1XB2drZlKCIiUswU2Sy+smXL4u7uzuzZs+nZs2dRhSEiIgZVJJMkcphMJqZOncrcuXM5e/ZsrnVjxozByckJgFatWjFx4sR7HqeoavGp5p6IiO2oFp+IiBiSHtQVERFDUoISERFDUoISERFDUoISERFDeugENXjwYI4cOQJAeno6zZs3JyQkxLp+0KBBjBo1iqioKOLj4+nbt+8dxwgKCiIqKirXsvj4eJo1a2Z9qLdv374MGTKExMTE+8Zki2keqrMnIlK0Hnqaedu2bTl06BCNGzfm8OHDtG3blt27dxMYGMjNmze5ePEiderUyVcw9evXJzQ01Pr5X//6F+vWrSMwMDDP/WxRi0919kREitZD96A8PT05dOgQAHv27MHf35/r169z/fp1vvvuO1q2bFkggVksFi5evEiFChUK5HgiIlK8PHSCatiwIWfOnMFisXDw4EFatmxJmzZt2L9/P9988w3t2rXLdzCnTp3CbDZjMpno2rUrf/nLX+jTp0++jyciIsXXQycoe3t7PDw8iIqKolq1ajg5OdG+fXu+/fZbDh8+jKenZ76DyRniCwsLo1atWlSpUoVSpYq02IWIiBSRfM3i8/LyYvHixdbeUvPmzfnf//4HQKVKlR45KGdnZ+bMmcPChQs5duzYIx9PRESKn3x1Tzw9PZkyZQqzZs0CwMnJifLly9OwYcM7tj158iS+vr7Wz0FBQQDMmDGDDz74AAB3d/c73r5btWpV3n77baZOncrq1auxt793LrVFLT7V2RMRKVqqxSciIoakB3VFRMSQlKBERMSQlKBERMSQSkSCKsi7aCpxJCJiDIX6kNHJkyeZPXs2aWlppKam0qFDB/72t79x6dIlgoODuXLlCjdu3OCZZ57hnXfewcnJiU6dOrFt2zZKly59z+MWZKkjlTgSETGGQutBJSUl8eabb/LOO+8QGhrK2rVrOXHiBCtXruT1119n6NCh1od0S5Uqxfz58wsrNBERMaBC60FFRkbSqlUr6tatC4CDgwMzZ87k6NGj1KhRgyZNmli3nTBhAtnZ2YUVmoiIGFChJaiEhARcXV1zLStbtuxdl+c1nCciIn8OhTbEV6tWLS5dupRrWVxcHNWrV79j+dWrV/n6668LKzQRETGgQutBdezYkcWLF9O/f3/c3NzIyMggODgYT09P4uPjOXLkCI0bN8ZisfDRRx9RunRpOnbs+EDHLshSRypxJCJiDIWWoMqVK0dwcDBTpkzBYrGQkpJCx44dGTBgAO3bt+cf//iHdXZf06ZNGTt27AMf286u4OJUchIRMQbV4hMREUMqEQ/qiohIyaMEJSIihqQEJSIihlQiElRB3UVTHT4REeN44Fl8S5YsYdmyZURGRlK6dGmCgoI4evQolSpVIjMzExcXFyZNmmR96PbAgQMsXLgQi8VCRkYGXbt2ZciQIdjZ2REbG8uMGTPIysoiMzOTRo0aMX78eOzt7bl48eI96/LdS0HV4lMdPhER43jgHtSWLVvw8fEhPPz/JYIJEyYQGhrKqlWrGDp0qHVq+MmTJ5k5cyZz5swhNDSU5cuXc/r0aUJCQgCYO3cugwYNIiQkhKVLl3L27FkiIyPJyspSXT4REQEeMEHFxMTg5uZGQEAAK1asuOs2LVq0wNHRkdjYWFatWsWrr77K448/DkCpUqUICgpizZo1wK2qEhs3buTw4cNkZmbywQcf4O3tzeHDh+9al2/UqFGP2k4RESlmHihBhYWF4e/vT7169XBycuKHH36463ZVqlTh6tWrxMXF4ebmlmtduXLlSEtLIzs7m3HjxtGkSRPmzp2Lp6cnkyZN4vr16/esy/fYY4/ls3kiIlJc3TdBJSYmEhUVxbJlywgMDCQ5OZnly5ffddsLFy5Qo0YNqlevzvnz53OtS05OxsnJCXt7ew4cOMCQIUNYsWIFu3fvpkyZMixcuPCu9fpUl09E5M/pvpMkNm/ejJ+fHxMnTgQgLS2NF154gUaNGuXabt++fTg7O1OjRg369+/P3//+d5o2bUq1atXIyMhgxowZBAQEADB79mwcHBzw8vKibNmyuLu7c/XqVZo2bZqvunwFVYtPdfhERIzjvqWOevXqxaxZs/Dw8LAue/fdd1m3bh3u7u5UqlQJe3t7ypYty7Rp06hevToAe/fuZfHixdaZep07d2bYsGHY29tz+vRppk+fTmJiIk5OTtSpU4d3332XcuXKERcXd0ddvqCgoDxn8anUkYhIyaNafCIiYkgl4kFdEREpeZSgRETEkJSgRETEkAo0QcXExNCgQQMiIiJyLTeZTAQFBZGRkcFHH33EgAEDMJvNvPLKK9ZnquLj42nQoAFLlizJte/IkSMxm815nvdR7qKp/p6IiDEV+Bt169Wrx9atW/Hx8QHg+PHjpKWlATB//nyysrJYvnw59vb2nD9/nldffZVPPvkEOzs73Nzc2L59OyNGjADg2rVrxMbGUrVq1TzP+Si1+FR/T0TEmAp8iM/Dw4OLFy+SlJQE3HqOymQyWf//5ptvYm9/67S1a9dmwIABbNy4EQAXFxeqVKnC6dOnAYiIiKBbt24FHaKIiBQDNrkH1blzZ3bs2IHFYuHIkSM899xz/P7771SsWJFSpXJ32lxdXblw4YL1c48ePawFaSMjI/H29rZFiCIiYnA2SVAmk4mIiAgOHjxIixYtAKhQoQKJiYlkZmbm2jY2NpaaNWtaP3t7e7Nr1y7i4+OpVq0azs7OtghRREQMziYJytXVldTUVEJDQ+nVqxcAjo6OdO/enXnz5pGdnQ1AXFwcK1euxNfX17pvTumj2bNn07NnT1uEJyIixUCBT5LI4ePjw6ZNm3B3dycuLg6At956iwULFtC3b18cHR1xcnJi+vTpuLq6Eh8fb93XZDIxdepU5s6dy9mzZ+97rkepxaf6eyIixqRSRyIiYkh6UFdERAxJCUpERAxJCUpERAxJCUpERAypUBLUkiVLaNu2LTdv3gQgKCgIk8mE2Wymf//+vP7669aZfvPmzWPy5MnWfaOjozGbzXc8P3W7u03zUI09EZHizWbTzG+3ZcsWfHx8CA8Ptz7zNGHCBNq3bw/AoUOHGDt2LOvXr+dvf/sbgwYNIiIigqZNm/L+++/z+eef31GB4nZ3q8WnGnsiIsWbzXtQMTExuLm5ERAQwIoVK+66TYsWLXB0dCQ2NpZSpUrxr3/9i7lz5zJ+/HimTJnC448/buswRUTEYGyeoMLCwvD396devXo4OTlZX6/xR1WqVOHq1avArSKyTZs2JTExkb/+9a+2DlFERAzIpgkqMTGRqKgoli1bRmBgIMnJySxfvvyu2164cIEaNWoAsHPnTi5fvsxzzz3H/PnzbRmiiIgYlE3vQW3evBk/Pz8mTpwIQFpaGi+88AKNGjXKtd2+fftwdnamRo0axMXFMXPmTEJDQ6lQoQJ+fn60adOGNm3a2DJUERExGJsmqLCwMGbNmmX9/Nhjj9GlSxfWrVvHxYsX+fTTT7G3t6ds2bJ88MEHpKenM3bsWIKCgqy9qTlz5jB69GjWrVtHlSpV7nqeu9XiU409EZHiTbX4RETEkPSgroiIGFKJ6EG1atWK2rVrF3UYIiKSDy4uLoSEhNyxvEQkKBERKXk0xCciIoakBCUiIoakBCUiIoakBCUiIoakBCUiIoakBCUiIoZk+ASVnZ3N1KlT6devH2azmdjY2Fzrd+3ahZ+fH/369WPt2rUPtE9RyE87MjIymDBhAgMGDOCll14iMjKyKELPJT/tyPH777/ToUMHTp8+XZgh31V+27F48WL69euHr68vYWFhhR32XeX3Z2v8+PEEBAQwYMCAYvE9gVv1PAMCAqzxFsdrHe5sR3G81uHOduQosGvdYnDbt2+3TJw40WKxWCzfffedZeTIkdZ16enpFm9vb8u1a9csN2/etPj6+loSEhLy3Keo5Kcd69ats0yfPt1isVgsV65csXTo0KEoQs8lP+3IWff6669bunTpYjl16lSRxH67/LTjwIEDlldffdWSlZVlSU5OtsyfP7+ows8lP23ZsWOH5Y033rBYLBZLdHS0ZfTo0UUS++3ud90eOXLE0qdPH4unp6f1Z6i4XesWy93bUdyudYvl7u2wWAr2Wjd8D+rw4cO0a9cOgKZNm/LTTz9Z150+fRo3NzcqVqyIk5MTzZs359ChQ3nuU1Ty045u3boxZswY63YODkVf/DY/7QCYOXMmAQEBhnn5ZH7aER0dzVNPPcWoUaMYOXIkzz//fBFFn1t+2uLu7k5WVhbZ2dkkJyfn+cbqwnK/6zY9PZ2PP/6YevXqPfA+RSE/7Shu1zrcvR1QsNd60f9U3kdycjLlypWzfnZwcCAzM5NSpUqRnJxM+fLlrevKli1LcnJynvsUlfy0o2zZstZ933jjDcaOHVvocf9RftqxYcMGKleuTLt27ViyZElRhH2H/LTj6tWrXLhwgUWLFhEfH89rr73Gl19+iZ2dXVE0wSo/bSlTpgznz5+ne/fuXL16lUWLFhVF6Lnc77pt3rz5Q+9TFPLTjuJ2rcPd21HQ17rhe1DlypUjJSXF+jk7O9v6BfrjupSUFMqXL5/nPkUlP+0AuHjxIoMHD6Z3796YTKbCDfou8tOO9evXs3//fsxmMz///DMTJ07k119/LfTYb5efdlSqVIm2bdvi5OREvXr1KF26NFeuXCn02P8oP21ZunQpbdu2Zfv27WzatImgoCBu3rxZ6LHfLj/XbXG71vNSnK71eynoa93wCapZs2ZERUUB8P333/PUU09Z1z3xxBPExsZy7do10tPTOXToEM8991ye+xSV/LTjt99+Y+jQoUyYMIGXXnqpqELPJT/tWLFiBcuXLyc0NJSnn36amTNnUq1ataJqApC/djRv3py9e/disVi4fPkyaWlpVKpUqaiaYJWftlSoUMH6R1DFihXJzMwkKyurSOLPkZ/rtrhd6/dS3K71eynoa93wQ3ydO3dm3759BAQEYLFYeO+999iyZQupqan069ePoKAgAgMDsVgs+Pn5Ub169bvuU9Ty047p06eTlJTEwoULWbhwIQCffvopzs7OxaodRpSfdlSvXp2DBw/y0ksvYbFYmDp1qiHuFeSnLUOGDOGdd95hwIABZGRkMG7cOMqUKWPodjzoPkUtP+1YtGhRsbvWC4OqmYuIiCEZfohPRET+nJSgRETEkJSgRETEkJSgRETEkJSgRETEkJSgRETEkJSgRETEkP4/ezAuEK2ppz4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "(mutual_info.groupby(mutual_info.index.to_series().str.split('_').str[-1])[1]\n",
    " .mean()\n",
    " .sort_values().plot.barh(title='Mutual Information with 1-Day Forward Returns'))\n",
    "sns.despine()\n",
    "plt.tight_layout()\n",
    "plt.savefig(results_path / 'mutual_info_cnn_features', dpi=300)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.847815Z",
     "start_time": "2020-06-21T21:45:29.845620Z"
    }
   },
   "outputs": [],
   "source": [
    "best_features = mi_by_indicator.head(15).index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:29.857701Z",
     "start_time": "2020-06-21T21:45:29.848932Z"
    }
   },
   "outputs": [],
   "source": [
    "size = len(best_features)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hierarchical Feature Clustering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:30.858863Z",
     "start_time": "2020-06-21T21:45:29.858980Z"
    }
   },
   "outputs": [],
   "source": [
    "features = pd.concat([features.filter(like=f'_{f}') for f in best_features], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:34.065461Z",
     "start_time": "2020-06-21T21:45:30.860027Z"
    }
   },
   "outputs": [],
   "source": [
    "new_cols = {}\n",
    "for feature in best_features:\n",
    "    fnames = sorted(features.filter(like=f'_{feature}').columns.tolist())\n",
    "    renamed = [f'{i:02}_{feature}' for i in range(1, len(fnames)+ 1)]\n",
    "    new_cols.update(dict(zip(fnames, renamed)))\n",
    "features = features.rename(columns=new_cols).sort_index(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:34.109152Z",
     "start_time": "2020-06-21T21:45:34.066673Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "MultiIndex: 2378283 entries, ('A', Timestamp('2001-01-02 00:00:00')) to ('ZTS', Timestamp('2017-12-28 00:00:00'))\n",
      "Columns: 225 entries, 01_BBH to 15_WMA\n",
      "dtypes: float64(225)\n",
      "memory usage: 4.0+ GB\n"
     ]
    }
   ],
   "source": [
    "features.info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Hierarchical Clustering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:45:34.114848Z",
     "start_time": "2020-06-21T21:45:34.110566Z"
    }
   },
   "outputs": [],
   "source": [
    "def cluster_features(data, labels, ax, title):\n",
    "    data = StandardScaler().fit_transform(data)\n",
    "    pairwise_distance = pdist(data)\n",
    "    Z = linkage(data, 'ward')\n",
    "    c, coph_dists = cophenet(Z, pairwise_distance)\n",
    "    dend = dendrogram(Z,\n",
    "                      labels=labels,\n",
    "                      orientation='top',\n",
    "                      leaf_rotation=0.,\n",
    "                      leaf_font_size=8.,\n",
    "                      ax=ax)\n",
    "    ax.set_title(title)\n",
    "    return dend['ivl']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:46:29.635173Z",
     "start_time": "2020-06-21T21:45:34.115905Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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119/3QwYMMBZ7k9/+pMpKCgwDofDhIeHmxUrVlzUnpUrV5o2bdqYxx57zPnfpEmTjDHGbN682URFRZlffvnFGGPM559/brp162aMMWbmzJnm3XffNcYY43A4TI8ePcxHH31kjDHmz3/+s/m///s/Zzv+/ve/O+u78HGXLl3MokWLnF+Ljo42a9asMcYYc/r0aRMdHW1Wr15tvvrqK9OtWzdTVFRkjDFm9uzZJjMz87LX+cLruX//fhMQEGA+++wzY8y571NoaKgxxpgXXnjBjB071hQVFZmjR4+azp07mwULFjjbl52dbb777jvToUMH8+OPPxpjjFm6dKmZNGmS+eabb8zw4cNNYWGhMcaYxYsXm7/+9a8Xfc82bdpkHnzwQXP06FHn1x555BFTVFRkYmNjTf/+/Z1tfvLJJ80HH3xgjDHmu+++M5MnT75iPwEA7iMgIMD06NHD9OjRwwQFBZmuXbuaadOmmSNHjhhjjHnppZfMsGHDjMPhMIWFhSYuLs5MmjTJHDhwwHTs2NEUFhaajIwMExQUZJ577jljjDGzZs0ySUlJF9UVGxtrgoODi93D09LSjDHGLFy40MycOdN570xISDDx8fGmqKjI/PnPfzb/+9//jDHGHDp0yNx7773Oe9T5e6cxv94Hzzv/+Px99auvvjLGGHP8+HHz8MMPm/379zvP2blzZ3PgwAGzaNEi57giPz/fjBw50pw8efKy1/CLL74wjz76qDHm3D2zbdu25uDBg8YYY6ZOnWrGjh1rjDGmV69ezv5+/fXXpmnTpuaLL74w+/fvNzabzRhjzBtvvGH69etnTp06ZQoLC82IESPMO++8Y15//XXn+KuoqMj85S9/Ma+99przup4fq1zq+3X+elw4jrnQb8dyRUVFZunSpaZHjx7GmMuPowICAsw777xjjDHGbrebiIgIc+zYMWOMMd9++62zb+evzY8//mgKCwtN9+7dneOS7777zrRs2dIUFhZedjx3YTv/97//mR49ejjr2rVrlwkKCjL5+flmwYIFJiwszJw5c8YYY8y4ceOc1+/w4cNm5MiRzvEQUNGYgQGUEw8PD+dfzi9l/fr1SklJkcVikbe3t/r27as33nhDMTExV11Ply5d5OXlpVtuuUV16tRRSEiIJMnf31/Hjx93lgsJCZG3t7ckKSAgQCdOnCjxfJf6CEl6err27t1b7HOkJ0+e1PHjxzVmzBht3LhRS5Ys0Z49e3T48GHnXz6uRbt27SRJv/zyi7766iudOHFCL730kvPYjh07FBwcLE9PT/Xp00fBwcEKCwtTYGDgNdXj5eWl+++/X5LUrFkz53XKyMjQ+PHjZbFY5OfnV+JfTzIyMhQcHKzbbrtN0rnpuufdcMMNSk1N1f79+7V58+YSZ7h8/vnn6t69u3M6ce/evfXCCy/ohx9+kCTnjA9JeuSRRzR16lR99tlnuu+++/Tcc89dUz8BAK53/iMkOTk5iomJUYcOHXTTTTdJOjcOGDVqlLy8vCRJ0dHReuaZZzR16lTddttt2rZtmz7//HPFxMQoKSlJxhh99tlnSkpKKrGuS32EJD09XXl5edq0aZOkczM/brrpJlksFr366qtKT0/XBx98oN27d8sYo1OnTl1TH2vUqCGbzSZJysrKUm5urp555hnn1y0Wi3bu3KmQkBDFxMTo4MGDuu+++/T888/L19f3mupq3ry56tevL+ncPfyTTz7Rzz//rJ07dyo8PFzSuXtpSR/72LRpk3r16qVatWpJkubPn+/82tdff62lS5dqz549+v7779WqVauLnn+p79d558cxJfn666/Vq1cvWSwWORwONW7cWAsWLJCkK46jzp/Xx8dHr776qtatW6c9e/Zox44dxcq1bNnSOT5p0KCBgoOD5eHhoYYNG6qgoECnTp267HjuQhs3btThw4eLjXMsFov27dsnSbLZbM4Zww899JBiY2OVnZ2tTp06aeLEifLwYGlFVA4CDKCcBAYG6r///a/sdrvzIySS9NNPP2nSpElasGCBioqKZLFYnF8rKirS2bNni53HYrHIGON8fObMmWJfPx9KnHepz1Gev1mXdM6rUVRUpF69emnMmDHOx4cPH9YNN9ygUaNGqbCwUI888ohCQ0N18ODBEs9/pb7UqVPHeW5jjFJTU1W7dm1J0rFjx1SzZk35+PjoX//6l7755ht98cUXGjlypAYNGnRNUxW9vLycN9YLr7+kYu3z9PS86Lmenp7FnnP69GkdOHBA+/fv1wsvvKABAwbogQceUOPGjfXee+9d9PySQi1jjPP7fv4aSFLfvn3VpUsXbdy4UZ9//rkWLVqkjz76SDVr1rzqvgIA3EPz5s01btw4xcXF6d5771WDBg1KHAecvzc++OCDWr9+vTZu3KjFixfrgw8+0IcffqhatWrJ39//muouKirS+PHjneF9fn6+CgoK9Msvv+iPf/yjHnzwQbVr106PP/64Pv3000uOES48fuGC5N7e3s7xR2Fhoe66665iH3H56aef5OfnJy8vL61Zs0YZGRn64osv1KdPHy1ZskQtWrS46r5cbjxz4f+XNB767bEjR46oqKhIb7zxhrKzs/X444+rQ4cOOnv2bInX4HLfL6n4Pfy3LrfG2HPPPXfZcdT58x46dEh/+tOfFBERobZt26pbt25au3ats9zVjAkvN577bblOnToVC3kOHjyo3/3ud/rkk0+K9bVLly76+OOPtWnTJmVkZOjll1/WqlWrnEETUJGIyoBycuutt6pnz54aP3687Ha7JMlut2vy5Mm68cYbVatWLQUHB+vNN9+UMUYOh0NpaWm67777ip3Hz89P33//vQoKCnTmzBl9/PHHruiOgoODtXr1ah0+fFiSlJKSov79+0uSNmzYoGeeeUbdu3eXJG3ZskWFhYWSzr3hP//mvF69etq2bZukc4OZL7/8ssS6rFarbDabli5dKuncXwYiIyO1Zs0arV27Vk899ZRat26t4cOHKzw83HnOsgoJCdGKFStUVFSkEydOlLj7SocOHZSRkeG8DqmpqZozZ442btyoLl26KCoqSi1atNCnn35a4jUICQnRhx9+6FzVfeXKlbrxxht15513XlRX37599d1336l3796aNm2aTp48qdzc3HLpKwCg8vXo0UOBgYGaMWOGpHP3hJSUFJ05c0ZFRUV66623FBQUJEl6+OGH9f7776uoqEi33nqrgoKCNGfOHD388MPXXG9wcLDeeustORwOFRUVadKkSZo3b5727t0ru92ukSNHqmvXrtq8ebOzjFT8/uXn5+e8327evPmS9yObzaa9e/fqq6++kiR99913CgsL008//aS5c+cqMTFRDz74oCZMmKAmTZro+++/v+b+/Fa9evXUvHlzZ2iSk5OjXbt2XVSuU6dO+uCDD5x9nDx5slavXq0NGzaof//+Cg8P10033aRNmzZd8h5+qe9XWVxuHHWhbdu2yc/PT08//bSCg4Od4UVJZS/lcuO5C/vaqVMnbdy4Ubt375YkrVu3To899phOnz590Tmff/55ffjhh3r00UcVHx8vq9XqnKkBVDRmYADlKD4+XomJierbt688PT3l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16pVq9S+ffsSr8HatWtLvPaSNHz4cNlsNhljNGTIEHXu3Fl16tS5pnZc62vx1KlT2r59uxo2bKht27apRYsWpb4G5/32dbh7927Vr19fW7ZsUatWrfTRRx85X+9HjhyRJP373/9WTEyM1qxZo/vuu0933HFHqcOLKynpOpSXkl4HK1eu1KFDh3T48GH17NlTfn5+WrhwoZo1ayZJKigo0OjRo/Xkk0/Kbrfrk08+UWFhoVq2bClJ2rZtm3bv3n1Nuxl89913uuOOOzRixAidOXNGa9askc1m08cff6xu3bppz5498vLycpbv3r27YmJidOzYMY0ZM6bcAgzp15/JrVu36u233y72M9mnTx8VFhaWW13u3Ibf/lysW7dOHTt2VJ8+fXTkyBHt3LlTTZo0qZC6L/y9+MMPP+jLL7/UO++8o5YtWyojI6PYvWf58uUaMWKE/vGPf5Q5wAgKCtLXX3+thg0bqn379vriiy8UFRWlr7/+Wo0aNdJXX32lQYMGyW636+TJk84BzrfffqumTZtq06ZNGjBggGrVqlWmdlRHubm5evvtt1W7dm2XtWHp0qXOYL6yffnll7r55pslSa1bt3ZJG06ePKnp06fLarVq4MCBLmlDXl6exo4dq/r162v48OGVHmD897//1ebNm9WiRQuXfR8++OADPfvss7rnnns0atQoPfDAA5X6c7F06VLVr19fP/74o4KCgiqt3gv169dP0rk/zi1atKhS6/7t76KjR49q5cqVqlevnkvq37Vrl1q2bCkPD48Ku6derg35+fkKCQlRly5d9PHHH2vjxo3q27dvpdUvSffcc4+6deumv//978rJyVGnTp0qtP7ftqGgoEBff/21Xn31VX3xxRdKS0urlGDvwjbs2rVLGzZsqJD3EtXmIyS7du1yvmGVpF69eqlevXp6/PHH9e6772r37t26++67JZ37y+hNN93kfJF5enoqKChIO3fuLHM7UlJS9Pzzz6tXr166/fbbtXXrVnXs2NH59QceeEDbt2/X999/X6y9oaGhZQovJCksLEyFhYX65JNPJJ17Y1yrVi317t1b7777rhwOR4nP27Vrl+Li4hQREaE33nhDAwYMKFM7UlJSNG7cOI0dO1b9+/d3nn/cuHE6fvy47rvvPh06dKjYm8GuXbtq+/btZao3LCzM+cbzyJEjql+/vvbt23fR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\n",
      "text/plain": [
       "<Figure size 1080x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axes = plt.subplots(figsize=(15, 4), ncols=2)\n",
    "\n",
    "labels = sorted(best_features)\n",
    "title = 'Column Features: Indicators'\n",
    "col_order = cluster_features(features.dropna().values.reshape(-1, 15).T,\n",
    "                             labels,\n",
    "                             axes[0],\n",
    "                             title)\n",
    "\n",
    "labels = list(range(1, 16))\n",
    "title = 'Row Features: Indicator Parameters'\n",
    "row_order = cluster_features(\n",
    "    features.dropna().values.reshape(-1, 15, 15).transpose((0, 2, 1)).reshape(-1, 15).T,\n",
    "    labels, axes[1], title)\n",
    "axes[0].set_xlabel('Indicators')\n",
    "axes[1].set_xlabel('Parameters')\n",
    "sns.despine()\n",
    "fig.tight_layout()\n",
    "fig.savefig(results_path / 'cnn_clustering', dpi=300)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:46:29.638912Z",
     "start_time": "2020-06-21T21:46:29.636916Z"
    }
   },
   "outputs": [],
   "source": [
    "feature_order = [f'{i:02}_{j}' for i in row_order for j in col_order]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:46:30.353888Z",
     "start_time": "2020-06-21T21:46:29.640540Z"
    }
   },
   "outputs": [],
   "source": [
    "features = features.loc[:, feature_order]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:46:31.026810Z",
     "start_time": "2020-06-21T21:46:30.354914Z"
    }
   },
   "outputs": [],
   "source": [
    "features = features.apply(pd.to_numeric, downcast='float')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:46:31.035967Z",
     "start_time": "2020-06-21T21:46:31.027859Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "MultiIndex: 2378283 entries, ('A', Timestamp('2001-01-02 00:00:00')) to ('ZTS', Timestamp('2017-12-28 00:00:00'))\n",
      "Columns: 225 entries, 01_CMO to 11_WMA\n",
      "dtypes: float32(225)\n",
      "memory usage: 2.0+ GB\n"
     ]
    }
   ],
   "source": [
    "features.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-06-21T21:46:33.630478Z",
     "start_time": "2020-06-21T21:46:31.037114Z"
    }
   },
   "outputs": [],
   "source": [
    "features.to_hdf('data.h5', 'img_data')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": true,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
